import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { NbAuthJWTToken, NbAuthService } from '@nebular/auth';
import { SettingService } from './setting.service';
import { UserDto, UserAccount, UserMapDto, UidsDto } from '../dto/index';
import { Result, IsFriend } from '../interfaces';
import { Observable } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';

@Injectable({ providedIn: 'root' })
export class UserService {

  private baseURL = this.settingService.getEndpoint('baseURL');
  private uid: string;

  constructor(
    private http: HttpClient,
    private _authService: NbAuthService,
    private settingService: SettingService,
  ) {}

  /**保存当前用户uid */
  get uId(): string {
    this._authService.getToken().subscribe((token: NbAuthJWTToken) => {
      const tokenUser = token.getPayload();
      this.uid = tokenUser.sub;
    });
    return this.uid;
  }

  /**
   * @function 获取所有用户
   */
  public getAllUsers() {
    const url = this.baseURL + '/all-users';
    return this.http.get(url);
  }

  /**
   * @function 获取用户账户信息
   */
  public getUserAccount(): Observable<UserAccount> {
    const url = this.baseURL + '/profile';
    return this.http.get<Result<UserAccount>>(url).pipe(
      map(({value}) => value),
    );
  }

  /**
   * @function 创建新用户（注册）
   */
  public createUser(user: UserDto) {
    const url = this.baseURL + '/auth/create-user';
    return this.http.post(url, user);
  }

  /**
   * @function 根据uid查询用户信息
   */
  public getUserById(uid: string): Observable<UserDto> {
    const url = `${this.baseURL}/userId/${uid}`;
    return this.http.get<Result<UserDto>>(url).pipe(
      map(({value}) => value),
    );
  }

  /**
   * @function 根据email查询用户信息
   */
  public getUserByEmail(email: string): Observable<UserDto> {
    const url = `${this.baseURL}/userEmail/${email}`;
    return this.http.get<Result<UserDto>>(url).pipe(
      map(({value}) => value),
    );
  }

  /**
   * @function 根据uid查询用户好友列表
   */
  public getFriendsList(uid: string): Observable<UserDto[]> {
    const url = `${this.baseURL}/friend/${uid}`;
    return this.http.get<Result<UserMapDto[]>>(url).pipe(
      switchMap(res => this._transformIdToList(res.value)),
    );
  }

  /**根据id数组查询好友 */
  private _transformIdToList(value: UserMapDto[]): Observable<UserDto[]> {
    const friendIds = value.map((userMap) => (userMap.friendId));
    const url = `${this.baseURL}/userIds`;
    return this.http.post<Result<UserDto[]>>(url, friendIds).pipe(
      map(({value}) => value),
    );
  }

  /**
   * @function 判断两人是否为好友
   */
  public isFriend(uids: UidsDto): Observable<IsFriend> {
    const url = `${this.baseURL}/isFriend`;
    return this.http.post<IsFriend>(url, uids);
  }

}